home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS / support / set / set.c next >
Encoding:
C/C++ Source or Header  |  1994-09-14  |  14.8 KB  |  792 lines  |  [TEXT/MPS ]

  1. /*    set.c
  2.  
  3.     The following is a general-purpose set library originally developed
  4.     by Hank Dietz and enhanced by Terence Parr to allow dynamic sets.
  5.     
  6.     Sets are now structs containing the #words in the set and
  7.     a pointer to the actual set words.
  8.     
  9.     Generally, sets need not be explicitly allocated.  They are
  10.     created/extended/shrunk when appropriate (e.g. in set_of()).
  11.     HOWEVER, sets need to be destroyed (free()ed) when they go out of scope
  12.     or are otherwise no longer needed.  A routine is provided to
  13.     free a set.
  14.     
  15.     Sets can be explicitly created with set_new(s, max_elem).
  16.     
  17.     Sets can be declared to have minimum size to reduce realloc traffic.
  18.     Default minimum size = 1.
  19.     
  20.     Sets can be explicitly initialized to have no elements (set.n == 0)
  21.     by using the 'empty' initializer:
  22.     
  23.     Examples:
  24.         set a = empty;    -- set_deg(a) == 0
  25.         
  26.         return( empty );
  27.     
  28.     Example set creation and destruction:
  29.     
  30.     set
  31.     set_of2(e,g)
  32.     unsigned e,g;
  33.     {
  34.         set a,b,c;
  35.         
  36.         b = set_of(e);        -- Creates space for b and sticks in e
  37.         set_new(c, g);        -- set_new(); set_orel() ==> set_of()
  38.         set_orel(g, &c);
  39.         a = set_or(b, c);
  40.         .
  41.         .
  42.         .
  43.         set_free(b);
  44.         set_free(c);
  45.         return( a );
  46.     }
  47.  
  48.     1987 by Hank Dietz
  49.     
  50.     Modified by:
  51.         Terence Parr
  52.         Purdue University
  53.         October 1989
  54.  
  55.     Made it smell less bad to C++ 7/31/93 -- TJP
  56. */
  57.  
  58. #include <stdio.h>
  59. #ifdef __cplusplus
  60. #ifndef __STDC__
  61. #define __STDC__
  62. #endif
  63. #endif
  64. #ifdef __STDC__
  65. #include <stdlib.h>
  66. #else
  67. #include <malloc.h>
  68. #endif
  69. #include <string.h>
  70.  
  71. #include "set.h"
  72.  
  73. /* elems can be a maximum of 32 bits */
  74. static unsigned bitmask[] = {
  75.     0x00000001, 0x00000002, 0x00000004, 0x00000008,
  76.     0x00000010, 0x00000020, 0x00000040, 0x00000080,
  77.     0x00000100, 0x00000200, 0x00000400, 0x00000800,
  78.     0x00001000, 0x00002000, 0x00004000, 0x00008000,
  79. #ifndef PC
  80.     0x00010000, 0x00020000, 0x00040000, 0x00080000,
  81.     0x00100000, 0x00200000, 0x00400000, 0x00800000,
  82.     0x01000000, 0x02000000, 0x04000000, 0x08000000,
  83.     0x10000000, 0x20000000, 0x40000000, 0x80000000
  84. #endif
  85. };
  86.  
  87. set empty = set_init;
  88. static unsigned min=1;
  89.  
  90. #define StrSize        200
  91.  
  92. #ifdef MEMCHK
  93. #define CHK(a)                    \
  94.     if ( a.setword != NULL )    \
  95.       if ( !valid(a.setword) )    \
  96.         {fprintf(stderr, "%s(%d): invalid set\n",__FILE__,__LINE__); exit(-1);}
  97. #else
  98. #define CHK(a)
  99. #endif
  100.  
  101. /*
  102.  * Set the minimum size (in words) of a set to reduce realloc calls
  103.  */
  104. void
  105. #ifdef __STDC__
  106. set_size( unsigned n )
  107. #else
  108. set_size( n )
  109. unsigned n;
  110. #endif
  111. {
  112.     min = n;
  113. }
  114.  
  115. unsigned int
  116. #ifdef __STDC__
  117. set_deg( set a )
  118. #else
  119. set_deg( a )
  120. set a;
  121. #endif
  122. {
  123.     /* Fast compute degree of a set... the number
  124.        of elements present in the set.  Assumes
  125.        that all word bits are used in the set
  126.        and that SETSIZE(a) is a multiple of WORDSIZE.
  127.     */
  128.     register unsigned *p = &(a.setword[0]);
  129.     register unsigned *endp = &(a.setword[a.n]);
  130.     register unsigned degree = 0;
  131.  
  132.     CHK(a);
  133.     if ( a.n == 0 ) return(0);
  134.     while ( p < endp )
  135.     {
  136.         register unsigned t = *p;
  137.         register unsigned *b = &(bitmask[0]);
  138.         do {
  139.             if (t & *b) ++degree;
  140.         } while (++b < &(bitmask[WORDSIZE]));
  141.         p++;
  142.     }
  143.  
  144.     return(degree);
  145. }
  146.  
  147. set
  148. #ifdef __STDC__
  149. set_or( set b, set c )
  150. #else
  151. set_or( b, c )
  152. set b;
  153. set c;
  154. #endif
  155. {
  156.     /* Fast set union operation */
  157.     /* resultant set size is max(b, c); */
  158.     set *big;
  159.     set t;
  160.     unsigned int m,n;
  161.     register unsigned *r, *p, *q, *endp;
  162.  
  163.     CHK(b); CHK(c);
  164.     t = empty;
  165.     if (b.n > c.n) {big= &b; m=b.n; n=c.n;} else {big= &c; m=c.n; n=b.n;}
  166.     set_ext(&t, m);
  167.     r = t.setword;
  168.  
  169.     /* Or b,c until max of smaller set */
  170.     q = c.setword;
  171.     p = b.setword;
  172.     endp = &(b.setword[n]);
  173.     while ( p < endp ) *r++ = *p++ | *q++;    
  174.  
  175.     /* Copy rest of bigger set into result */
  176.     p = &(big->setword[n]);
  177.     endp = &(big->setword[m]);
  178.     while ( p < endp ) *r++ = *p++;
  179.  
  180.     return(t);
  181. }
  182.  
  183. set
  184. #ifdef __STDC__
  185. set_and( set b, set c )
  186. #else
  187. set_and( b, c )
  188. set b;
  189. set c;
  190. #endif
  191. {
  192.     /* Fast set intersection operation */
  193.     /* resultant set size is min(b, c); */
  194.     set t;
  195.     unsigned int n;
  196.     register unsigned *r, *p, *q, *endp;
  197.  
  198.     CHK(b); CHK(c);
  199.     t = empty;
  200.     n = (b.n > c.n) ? c.n : b.n;
  201.     if ( n == 0 ) return t;        /* TJP 4-27-92 fixed for empty set */
  202.     set_ext(&t, n);
  203.     r = t.setword;
  204.  
  205.     /* & b,c until max of smaller set */
  206.     q = c.setword;
  207.     p = b.setword;
  208.     endp = &(b.setword[n]);
  209.     while ( p < endp ) *r++ = *p++ & *q++;    
  210.  
  211.     return(t);
  212. }
  213.  
  214. set
  215. #ifdef __STDC__
  216. set_dif( set b, set c )
  217. #else
  218. set_dif( b, c )
  219. set b;
  220. set c;
  221. #endif
  222. {
  223.     /* Fast set difference operation b - c */
  224.     /* resultant set size is size(b) */
  225.     set t;
  226.     unsigned int n;
  227.     register unsigned *r, *p, *q, *endp;
  228.  
  229.     CHK(b); CHK(c);
  230.     t = empty;
  231.     n = (b.n <= c.n) ? b.n : c.n ;
  232.     if ( b.n == 0 ) return t;        /* TJP 4-27-92 fixed for empty set */
  233.                                     /* WEC 12-1-92 fixed for c.n = 0 */
  234.     set_ext(&t, b.n);
  235.     r = t.setword;
  236.  
  237.     /* Dif b,c until smaller set size */
  238.     q = c.setword;
  239.     p = b.setword;
  240.     endp = &(b.setword[n]);
  241.     while ( p < endp ) *r++ = *p++ & (~ *q++);    
  242.  
  243.     /* Copy rest of b into result if size(b) > c */
  244.     if ( b.n > n )
  245.     {
  246.         p = &(b.setword[n]);
  247.         endp = &(b.setword[b.n]);
  248.         while ( p < endp ) *r++ = *p++;
  249.     }
  250.  
  251.     return(t);
  252. }
  253.  
  254. set
  255. #ifdef __STDC__
  256. set_of( unsigned b )
  257. #else
  258. set_of( b )
  259. unsigned b;
  260. #endif
  261. {
  262.     /* Fast singleton set constructor operation */
  263.     static set a;
  264.  
  265.     if ( b == nil ) return( empty );
  266.     set_new(a, b);
  267.     a.setword[DIVWORD(b)] = bitmask[MODWORD(b)];
  268.  
  269.     return(a);
  270. }
  271.  
  272. /*
  273.  * Extend (or shrink) the set passed in to have n words.
  274.  *
  275.  * if n is smaller than the minimum, boost n to have the minimum.
  276.  * if the new set size is the same as the old one, do nothing.
  277.  *
  278.  * TJP 4-27-92 Fixed so won't try to alloc 0 bytes
  279.  */
  280. void
  281. #ifdef __STDC__
  282. set_ext( set *a, unsigned int n )
  283. #else
  284. set_ext( a, n )
  285. set *a;
  286. unsigned int n;
  287. #endif
  288. {
  289.     register unsigned *p;
  290.     register unsigned *endp;
  291.     unsigned int size;
  292.     
  293.     CHK((*a));
  294.     if ( a->n == 0 )
  295.     {
  296.         if ( n == 0 ) return;
  297.         a->setword = (unsigned *) calloc(n, BytesPerWord);
  298.         if ( a->setword == NULL )
  299.         {
  300.             fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n);
  301.             exit(-1);
  302.         }
  303.         a->n = n;
  304.         return;
  305.     }
  306.     if ( n < min ) n = min;
  307.     if ( a->n == n || n == 0 ) return;
  308.     size = a->n;
  309.     a->n = n;
  310.     a->setword = (unsigned *) realloc( (char *)a->setword, (n*BytesPerWord) );
  311.     if ( a->setword == NULL )
  312.     {
  313.         fprintf(stderr, "set_ext(%d words): cannot allocate set\n", n);
  314.         exit(-1);
  315.     }
  316.  
  317.     p    = &(a->setword[size]);        /* clear from old size to new size */
  318.     endp = &(a->setword[a->n]);
  319.     do {
  320.         *p++ = 0;
  321.     } while ( p < endp );
  322. }
  323.  
  324. set
  325. #ifdef __STDC__
  326. set_not( set a )
  327. #else
  328. set_not( a )
  329. set a;
  330. #endif
  331. {
  332.     /* Fast not of set a (assumes all bits used) */
  333.     /* size of resultant set is size(a) */
  334.     /* ~empty = empty cause we don't know how bit to make set */
  335.     set t;
  336.     register unsigned *r;
  337.     register unsigned *p = a.setword;
  338.     register unsigned *endp = &(a.setword[a.n]);
  339.  
  340.     CHK(a);
  341.     t = empty;
  342.     if ( a.n == 0 ) return( empty );
  343.     set_ext(&t, a.n);
  344.     r = t.setword;
  345.     
  346.     do {
  347.         *r++ = (~ *p++);
  348.     } while ( p < endp );
  349.  
  350.     return(t);
  351. }
  352.  
  353. int
  354. #ifdef __STDC__
  355. set_equ( set a, set b )
  356. #else
  357. set_equ( a, b )
  358. set a;
  359. set b;
  360. #endif
  361. {
  362.     /* Fast set equality comparison operation */
  363.     register unsigned *p = a.setword;
  364.     register unsigned *q = b.setword;
  365.     register unsigned *endp = &(a.setword[a.n]);
  366.  
  367.     CHK(a); CHK(b);
  368.     if ( a.n != b.n ) return(0);
  369.     else if ( a.n==0 ) return(1);    /* empty == empty */
  370.     
  371.     do {
  372.         if (*p != *q) return(0);
  373.         ++q;
  374.     } while ( ++p < endp );
  375.  
  376.     return(1);
  377. }
  378.  
  379. int
  380. #ifdef __STDC__
  381. set_sub( set a, set b )
  382. #else
  383. set_sub( a, b )
  384. set a;
  385. set b;
  386. #endif
  387. {
  388.     /* Fast check for a is a proper subset of b (alias a < b) */
  389.     register unsigned *p = a.setword;
  390.     register unsigned *q = b.setword;
  391.     register unsigned *endp = &(a.setword[a.n]);
  392.     register int asubset = 0;
  393.  
  394.     CHK(a); CHK(b);
  395.     if ( set_deg(a) > set_deg(b) ) return(0);
  396.     if ( set_deg(a)==0 && set_deg(b)==0) return(1);/* empty prop sub of empty */
  397.     if ( set_deg(a) == 0 ) return(1);        /* empty is sub of everything */
  398. #ifdef DUH
  399. /* Was: */
  400.     if ( a.n > b.n ) return(0);
  401.     if (a.n==0 && b.n==0) return(1);/* empty prop sub of empty */
  402.     if ( a.n == 0 ) return(1);        /* empty is sub of everything */
  403. #endif
  404.  
  405.     do {
  406.         /* Prune tests based on guess that most set words
  407.            will match, particularly if a is a subset of b.
  408.         */
  409.         if (*p != *q) {
  410.             if (*p & ~(*q)) {
  411.                 /* Fail -- a contains something b does not */
  412.                 return(0);
  413.             }
  414.             /* At least this word was a proper subset, hence
  415.                even if all other words are equal, a is a
  416.                proper subset of b.
  417.             */
  418.             asubset = 1;
  419.         }
  420.         ++q;
  421.     } while (++p < endp);
  422.  
  423.     /* at this point, a,b are equ or a subset */
  424.     if ( asubset || b.n == a.n ) return(asubset);
  425.     
  426.     /* if !asubset, size(b) > size(a), then a=b and must check rest of b */
  427.     p = q;
  428.     endp = &(b.setword[b.n]);
  429.     do
  430.     {
  431.         if ( *p++ ) return(1);
  432.     } while ( p < endp );
  433.  
  434.     return(0);
  435. }
  436.  
  437. unsigned
  438. #ifdef __STDC__
  439. set_int( set b )
  440. #else
  441. set_int( b )
  442. set b;
  443. #endif
  444. {
  445.     /* Fast pick any element of the set b */
  446.     register unsigned *p = b.setword;
  447.     register unsigned *endp = &(b.setword[b.n]);
  448.  
  449.     CHK(b);
  450.     if ( b.n == 0 ) return( nil );
  451.  
  452.     do {
  453.         if (*p) {
  454.             /* Found a non-empty word of the set */
  455.             register unsigned i = ((p - b.setword) << LogWordSize);
  456.             register unsigned t = *p;
  457.             p = &(bitmask[0]);
  458.             while (!(*p & t)) {
  459.                 ++i; ++p;
  460.             }
  461.             return(i);
  462.         }
  463.     } while (++p < endp);
  464.  
  465.     /* Empty -- only element it contains is nil */
  466.     return(nil);
  467. }
  468.  
  469. int
  470. #ifdef __STDC__
  471. set_el( unsigned b, set a )
  472. #else
  473. set_el( b, a )
  474. unsigned b;
  475. set a;
  476. #endif
  477. {
  478.     CHK(a);
  479.     /* nil is an element of every set */
  480.     if (b == nil) return(1);
  481.     if ( a.n == 0 || NumWords(b) > a.n ) return(0);
  482.     
  483.     /* Otherwise, we have to check */
  484.     return( a.setword[DIVWORD(b)] & bitmask[MODWORD(b)] );
  485. }
  486.  
  487. int
  488. #ifdef __STDC__
  489. set_nil( set a )
  490. #else
  491. set_nil( a )
  492. set a;
  493. #endif
  494. {
  495.     /* Fast check for nil set */
  496.     register unsigned *p = a.setword;
  497.     register unsigned *endp = &(a.setword[a.n]);
  498.  
  499.     CHK(a);
  500.     if ( a.n == 0 ) return(1);
  501.     /* The set is not empty if any word used to store
  502.        the set is non-zero.  This means one must be a
  503.        bit careful about doing things like negation.
  504.     */
  505.     do {
  506.         if (*p) return(0);
  507.     } while (++p < endp);
  508.     
  509.     return(1);
  510. }
  511.  
  512. char *
  513. #ifdef __STDC__
  514. set_str( set a )
  515. #else
  516. set_str( a )
  517. set a;
  518. #endif
  519. {
  520.     /* Fast convert set a into ASCII char string...
  521.        assumes that all word bits are used in the set
  522.        and that SETSIZE is a multiple of WORDSIZE.
  523.        Trailing 0 bits are removed from the string.
  524.        if no bits are on or set is empty, "" is returned.
  525.     */
  526.     register unsigned *p = a.setword;
  527.     register unsigned *endp = &(a.setword[a.n]);
  528.     static char str_tmp[StrSize+1];
  529.     register char *q = &(str_tmp[0]);
  530.  
  531.     CHK(a);
  532.     if ( a.n==0 ) {*q=0; return( &(str_tmp[0]) );}
  533.     do {
  534.         register unsigned t = *p;
  535.         register unsigned *b = &(bitmask[0]);
  536.         do {
  537.             *(q++) = (char) ((t & *b) ? '1' : '0');
  538.         } while (++b < &(bitmask[WORDSIZE]));
  539.     } while (++p < endp);
  540.  
  541.     /* Trim trailing 0s & NULL terminate the string */
  542.     while ((q > &(str_tmp[0])) && (*(q-1) != '1')) --q;
  543.     *q = 0;
  544.  
  545.     return(&(str_tmp[0]));
  546. }
  547.  
  548. set
  549. #ifdef __STDC__
  550. set_val( register char *s )
  551. #else
  552. set_val( s )
  553. register char *s;
  554. #endif
  555. {
  556.     /* Fast convert set ASCII char string into a set.
  557.        If the string ends early, the remaining set bits
  558.        are all made zero.
  559.        The resulting set size is just big enough to hold all elements.
  560.     */
  561.     static set a;
  562.     register unsigned *p, *endp;
  563.  
  564.     set_new(a, strlen(s));
  565.     p = a.setword;
  566.     endp = &(a.setword[a.n]);
  567.     do {
  568.         register unsigned *b = &(bitmask[0]);
  569.         /* Start with a word with no bits on */
  570.         *p = 0;
  571.         do {
  572.             if (*s) {
  573.                 if (*s == '1') {
  574.                     /* Turn-on this bit */
  575.                     *p |= *b;
  576.                 }
  577.                 ++s;
  578.             }
  579.         } while (++b < &(bitmask[WORDSIZE]));
  580.     } while (++p < endp);
  581.  
  582.     return(a);
  583. }
  584.  
  585. /*
  586.  * Or element e into set a.  a can be empty.
  587.  */
  588. void
  589. #ifdef __STDC__
  590. set_orel( unsigned e, set *a )
  591. #else
  592. set_orel( e, a )
  593. unsigned e;
  594. set *a;
  595. #endif
  596. {
  597.     CHK((*a));
  598.     if ( e == nil ) return;
  599.     if ( NumWords(e) > a->n ) set_ext(a, NumWords(e));
  600.     a->setword[DIVWORD(e)] |= bitmask[MODWORD(e)];
  601. }
  602.  
  603. /*
  604.  * Or set b into set a.  a can be empty. does nothing if b empty.
  605.  */
  606. void
  607. #ifdef __STDC__
  608. set_orin( set *a, set b )
  609. #else
  610. set_orin( a, b )
  611. set *a;
  612. set b;
  613. #endif
  614. {
  615.     /* Fast set union operation */
  616.     /* size(a) is max(a, b); */
  617.     unsigned int m;
  618.     register unsigned *p,
  619.                       *q    = b.setword,
  620.                       *endq = &(b.setword[b.n]);
  621.  
  622.     CHK((*a)); CHK(b);
  623.     if ( b.n == 0 ) return;
  624.     m = (a->n > b.n) ? a->n : b.n;
  625.     set_ext(a, m);
  626.     p = a->setword;
  627.     do {
  628.         *p++ |= *q++;
  629.     } while ( q < endq );
  630. }
  631.  
  632. void
  633. #ifdef __STDC__
  634. set_rm( unsigned e, set a )
  635. #else
  636. set_rm( e, a )
  637. unsigned e;
  638. set a;
  639. #endif
  640. {
  641.     /* Does not effect size of set */
  642.     CHK(a);
  643.     if ( (e == nil) || (NumWords(e) > a.n) ) return;
  644.     a.setword[DIVWORD(e)] ^= (a.setword[DIVWORD(e)]&bitmask[MODWORD(e)]);
  645. }
  646.  
  647. void
  648. #ifdef __STDC__
  649. set_clr( set a )
  650. #else
  651. set_clr( a )
  652. set a;
  653. #endif
  654. {
  655.     /* Does not effect size of set */
  656.     register unsigned *p = a.setword;
  657.     register unsigned *endp = &(a.setword[a.n]);
  658.     
  659.     CHK(a);
  660.     if ( a.n == 0 ) return;
  661.     do {
  662.         *p++ = 0;
  663.     } while ( p < endp );
  664. }
  665.  
  666. set
  667. #ifdef __STDC__
  668. set_dup( set a )
  669. #else
  670. set_dup( a )
  671. set a;
  672. #endif
  673. {
  674.     set b;
  675.     register unsigned *p,
  676.                       *q    = a.setword,
  677.                       *endq = &(a.setword[a.n]);
  678.     
  679.     CHK(a);
  680.     b = empty;
  681.     if ( a.n == 0 ) return( empty );
  682.     set_ext(&b, a.n);
  683.     p = b.setword;
  684.     do {
  685.         *p++ = *q++;
  686.     } while ( q < endq );
  687.     
  688.     return(b);
  689. }
  690.  
  691. /*
  692.  * Return a nil terminated list of unsigned ints that represents all
  693.  * "on" bits in the bit set.
  694.  *
  695.  * e.g. {011011} --> {1, 2, 4, 5, nil}
  696.  *
  697.  * _set_pdq and set_pdq are useful when an operation is required on each element
  698.  * of a set.  Normally, the sequence is:
  699.  *
  700.  *        while ( set_deg(a) > 0 ) {
  701.  *            e = set_int(a);
  702.  *            set_rm(e, a);
  703.  *            ...process e...
  704.  *        }
  705.  * Now,
  706.  *
  707.  *        t = e = set_pdq(a);
  708.  *        while ( *e != nil ) {
  709.  *            ...process *e...
  710.  *            e++;
  711.  *        }
  712.  *        free( t );
  713.  *
  714.  * We have saved many set calls and have not destroyed set a.
  715.  */
  716. void
  717. #ifdef __STDC__
  718. _set_pdq( set a, register unsigned *q )
  719. #else
  720. _set_pdq( a, q )
  721. set a;
  722. register unsigned *q;
  723. #endif
  724. {
  725.     register unsigned *p = a.setword,
  726.                       *endp = &(a.setword[a.n]);
  727.     register unsigned e=0;
  728.  
  729.     CHK(a);
  730.     /* are there any space (possibility of elements)? */
  731.     if ( a.n == 0 ) return;
  732.     do {
  733.         register unsigned t = *p;
  734.         register unsigned *b = &(bitmask[0]);
  735.         do {
  736.             if ( t & *b ) *q++ = e;
  737.             ++e;
  738.         } while (++b < &(bitmask[WORDSIZE]));
  739.     } while (++p < endp);
  740.     *q = nil;
  741. }
  742.  
  743. /*
  744.  * Same as _set_pdq except allocate memory.  set_pdq is the natural function
  745.  * to use.
  746.  */
  747. unsigned *
  748. #ifdef __STDC__
  749. set_pdq( set a )
  750. #else
  751. set_pdq( a )
  752. set a;
  753. #endif
  754. {
  755.     unsigned *q;
  756.     int max_deg;
  757.     
  758.     CHK(a);
  759.     max_deg = WORDSIZE*a.n;
  760.     /* assume a.n!=0 & no elements is rare, but still ok */
  761.     if ( a.n == 0 ) return(NULL);
  762.     q = (unsigned *) malloc((max_deg+1)*BytesPerWord);
  763.     if ( q == NULL ) return( NULL );
  764.     _set_pdq(a, q);
  765.     return( q );
  766. }
  767.  
  768. /* a function that produces a hash number for the set
  769.  */
  770. unsigned int
  771. #ifdef __STDC__
  772. set_hash( set a, register unsigned int mod )
  773. #else
  774. set_hash( a, mod )
  775. set a;
  776. register unsigned int mod;
  777. #endif
  778. {
  779.     /* Fast hash of set a (assumes all bits used) */
  780.     register unsigned *p = &(a.setword[0]);
  781.     register unsigned *endp = &(a.setword[a.n]);
  782.     register unsigned i = 0;
  783.  
  784.     CHK(a);
  785.     while (p<endp){
  786.         i += (*p);
  787.         ++p;
  788.     }
  789.  
  790.     return(i % mod);
  791. }
  792.